﻿using CJiaBao.Core.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace Core.Configuration.Utils
{

    public class HttpHelper
    {
        #region GET请求
        /// <summary>
        /// 使用get方法异步请求
        /// </summary>
        /// <param name="url">目标链接</param>
        /// <returns>返回的字符串</returns>
        public static async Task<string> GetAsync(string url, Dictionary<string, string> headers = null)
        {
            var client = CreateHttpClient(headers);

            var response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode(); //用来抛异常的
            return await response.Content.ReadAsStringAsync();
        }

        public static async Task<T> GetAsync<T>(string url)
        {
            string body = await GetAsync(url, null);
            return JsonHelper.ToObject<T>(body);
        }
        public static async Task<T> GetAsync<T>(string url, Dictionary<string, string> header)
        {
            string body = await GetAsync(url, header);
            return JsonHelper.ToObject<T>(body);
        }
        #endregion

        #region POST请求

        /// <summary>
        /// 使用post方法异步请求
        /// </summary>
        public static async Task<string> PostAsync(string url, string data, Dictionary<string, string> headers = null)
        {
            var client = CreateHttpClient(headers);
            var content = new StringContent(data);

            var response = await client.PostAsync(url, content);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }

        /// <summary>
        /// 使用post返回异步请求直接返回对象
        /// </summary>
        public static async Task<T> PostAsync<T>(string url, object model)
        {
            var data = JsonHelper.ToJson(model);
            var body = await PostAsync(url, data, null);
            return JsonHelper.ToObject<T>(body);
        }


        public static string Post(Uri url, string value, string cerPassword = "", string cerPath = "")
        {
            Trace.TraceInformation(url.ToString());
            Trace.TraceInformation(value);
            HttpWebRequest request;
            if (url.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
                request = (HttpWebRequest)WebRequest.CreateDefault(url);
                if (!string.IsNullOrEmpty(cerPassword) && File.Exists(cerPath))
                {
                    var cert = new X509Certificate2(cerPath, cerPassword, X509KeyStorageFlags.MachineKeySet);
                    request.ClientCertificates.Add(cert);
                }
            }
            else
            {
                request = (HttpWebRequest)WebRequest.Create(url);
            }
            request.ServicePoint.Expect100Continue = false;
            request.Method = "POST";
            request.KeepAlive = true;
            request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
            var bytes = Encoding.UTF8.GetBytes(value);
            var requestStream = request.GetRequestStream();
            requestStream.Write(bytes, 0, bytes.Length);
            requestStream.Close();
            var body = string.Empty;
            try
            {
                var res = (HttpWebResponse)request.GetResponse();

                using (var stream = res.GetResponseStream())
                {
                    if (stream == null) return string.Empty;
                    using (var reader = new StreamReader(stream, Encoding.UTF8))
                    {
                        body = reader.ReadToEnd();
                    }
                }
            }
            catch (WebException ex)
            {
                var res = (HttpWebResponse)ex.Response;
                var myResponseStream = res.GetResponseStream();
                var sr = new StreamReader(myResponseStream, Encoding.UTF8);
                body = sr.ReadToEnd();
                sr.Close();
            }
            Trace.TraceInformation(body);
            return body;
        }
        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        }
        private static HttpClient CreateHttpClient(Dictionary<string, string> headers)
        {
            var client = new HttpClient();
            if (headers != null)
            {
                client.DefaultRequestHeaders.Clear();
                foreach (var item in headers)
                {
                    client.DefaultRequestHeaders.Add(item.Key, item.Value);
                }
            }
            return client;
        }
        #endregion

        #region 上传下载
        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="url"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static async Task<string> UploadAsync(string url, string filePath)
        {
            FileStream file = null;
            var formData = new MultipartFormDataContent();
            try
            {
                file = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                //添加文件
                formData.Add(new StreamContent(file), "file", "file.png");

                var request = new HttpRequestMessage(HttpMethod.Post, url);
                request.Content = formData;

                var client = new HttpClient();
                var response = await client.SendAsync(request);

                response.EnsureSuccessStatusCode(); //用来抛异常的

                return await response.Content.ReadAsStringAsync();
            }
            catch { }
            finally
            {
                if (file != null) file.Close();
            }
            return string.Empty;
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        public static async Task<bool> DownloadAsync(string url, string directoryName, string fileName)
        {
            bool sign = true;
            try
            {
                if (!Directory.Exists(directoryName))
                    Directory.CreateDirectory(directoryName);

                var client = new HttpClient();
                var response = await client.GetAsync(url);
                using (var stream = await response.Content.ReadAsStreamAsync())
                {
                    int length;
                    byte[] buffer = new byte[10240];
                    using (var fs = new FileStream($"{directoryName}/{fileName}", FileMode.Create))
                    {
                        while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                        {
                            fs.Write(buffer, 0, length);
                        }
                    }
                }
            }
            catch
            {
                sign = false;
            }
            return sign;
        }
        #endregion     
    }
}
